package com.stox.downloader;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Date;

import com.stox.core.manager.InstallationManager;
import com.stox.core.model.Exchange;
import com.stox.core.model.IBar;
import com.stox.core.model.Scrip;
import com.stox.core.model.exception.StoxException;
import com.stox.core.util.StringUtil;
import com.stox.ioc.Container;

public abstract class AbstractDataProvider implements DataProvider {

	private InstallationManager installationManager;
	
	public AbstractDataProvider() {
		this.installationManager = Container.get(InstallationManager.class);
	}
	
	private String getRawDataFromFilebase(Date date, Exchange exchange){
		String rawData = "";
		  try{
	        	 BufferedReader bufferedReader = new BufferedReader(
			        		new FileReader(constructDownloadFilePath(date, exchange.getCode())));
	        	 String line = null;
	        	 while((line = bufferedReader.readLine()) != null){
	        		 rawData += line+"\n";
	        	 }
	        	 bufferedReader.close();
	        }catch(Exception e){

	        }
		  return rawData;
	}
	
	@SuppressWarnings("deprecation")
	private String constructDownloadFilePath(Date date, String exchangeCode){
		if(date != null && StringUtil.hasText(exchangeCode)){
			return installationManager.getFilebasePath()+
					File.separator+exchangeCode+
					File.separator+(date.getYear()+1900)+
					File.separator+(date.getMonth()+1)+
					File.separator+date.getDate()+".txt";
		}
		return null;
	}
	
	private String downloadRawData(Date date, Exchange exchange){
		String data = getRawDataFromFilebase(date, exchange);
        if(!StringUtil.hasText(data)){
        	String downloadUri = constructBreadthUri(date);
    		data = downloadRawData(downloadUri);
    		persistRawData(data, date, exchange);
        }
        return data;
	}
	
	private void persistRawData(String data, Date date, Exchange exchange){
		try{
			File file = new File(constructDownloadFilePath(date, exchange.getCode()));
			if(!file.exists()){
				file.getParentFile().mkdirs();
				file.createNewFile();
			}
			
			BufferedWriter writer = new BufferedWriter(
					new FileWriter(file));
			writer.write(data);
			writer.close();
		}catch(Throwable t){
			throw new StoxException(t);
		}
	}
	
	private DataStream parseRawData(String rawData, Date date, Exchange exchange){
		DataStream dataStream = getParser().parse(rawData);
        for(IBar bar : dataStream.getBarList()){
        	bar.setDate(date);
        }
        return dataStream;
	}
	
	@Override
	public DataStream get(Scrip scrip, Date start, Date end) {
		
		return null;
	}

	@Override
	public DataStream get(Exchange exchange, Date date) {
		return parseRawData(downloadRawData(date, exchange), date, exchange);
	}
	
	public abstract DataStreamParser getParser();
	public abstract String constructBreadthUri(Date date);
	public abstract String downloadRawData(String uri);

	public InstallationManager getInstallationManager() {
		return installationManager;
	}

	public void setInstallationManager(InstallationManager installationManager) {
		this.installationManager = installationManager;
	}

}
